| Working with the Viewer > Customizing the Viewer > Customization Examples > Adding Keyboard Shortcuts |
The Viewer includes minimal keyboard shortcuts, but more can be easily added by utilizing the ViewerControl API. This topic will walk through the general structure of adding keyboard shortcuts, as well as demonstrate some examples. These examples are meant to show some possibilities, and do not represent all that can be accomplished with keyboard shortcuts.
First, set up the Viewer as you would normally. The rest of this topic assumes that a working version of this code is available:
| Example |
Copy Code
|
|---|---|
function initKeyBindings (viewerControl) {
//we will be working here
}
var pluginOptions = {
documentID: viewingSessionId,
language: languageItems,
template: htmlTemplates
};
$(document).ready(function () {
var viewerControl = $("#viewer1").pccViewer(pluginOptions).viewerControl;
initKeyBindings(viewerControl);
});
|
|
Keyboard shortcuts are generally added to the documentobject, so that they can be available globally.
![]() |
Global keyboard listeners can cause some lag in applications that attempt to do a lot of work inside the key listeners while the user is typing text. It is a good idea to disconnect keyboard shortcut listeners (or greatly reduce the work being done) when the user is typing text (such as when a text area is offered). This portion will not be covered in this topic. |
| Example |
Copy Code
|
|---|---|
function handleGlobalKeypress (ev, viewerControl) {
switch (ev.keyCode) {
// check for keys here
}
}
function initKeyBindings (viewerControl) {
var handler = function(ev){
handleGlobalKeypress(ev, viewerControl);
};
$(document).on("keydown", handler);
}
|
|
![]() |
The example here uses jQuery, for maximum compatibility. If you prefer to use plain JavaScript, you may need to handle differences in attaching events, as well as slight differences in the event object, depending on your supported browsers. |
There are several things to consider here. First, not all keys are available in the keydown event in every browser. For example, the delete key does not trigger a "keydown" in most browsers, and the "Backspace" key will navigate away from the page before triggering any behavior. Here, you are using the keydown event, which will fire before the key has had any effect on the browser, and therefore, will allow complete overriding of the key behavior. There may be times when you prefer to have the key handled by the browser before checking for a keyboard shortcut, in which case it would be appropriate to use the keyup event.
In this example, you will use the Delete key to delete the currently selected annotations:
| Example |
Copy Code
|
|---|---|
function handleGlobalKeypress (ev, viewerControl) {
switch (ev.keyCode) {
case 46: // Delete
var selectedMarks = viewerControl.getSelectedMarks();
if (selectedMarks.length){
viewerControl.deleteMarks(selectedMarks);
}
break;
}
}
|
|
In this example, you will use the arrow keys to move the selected annotations up, down, left, and right, to allow for more precise editing. The code below will nudge all selected annotations by 2 pixels:
| Example |
Copy Code
|
|---|---|
function nudgeMarks (direction, viewerControl) {
var selectedMarks = viewerControl.getSelectedMarks();
if (selectedMarks.length){
var nudgeAmount = 2,
rectangle;
$.each(selectedMarks, function(i, mark){
rectangle = mark.getRectangle();
rectangle.x += direction.x ? (direction.x * nudgeAmount) : 0;
rectangle.y += direction.y ? (direction.y * nudgeAmount) : 0;
mark.setRectangle(rectangle);
});
}
}
function handleGlobalKeypress (ev, viewerControl) {
switch (ev.keyCode) {
case 37: // left arrow
nudgeMarks({ x: -1 }, viewerControl);
break;
case 38: // up arrow
nudgeMarks({ y: -1 }, viewerControl);
break;
case 39: // right arrow
nudgeMarks({ x: 1 }, viewerControl);
break;
case 40: // down arrow
nudgeMarks({ y: 1 }, viewerControl);
break;
}
}
|
|
In this example, you will use the Page Up and Page Down keyboard keys to navigate pages. Since these keys have a default behavior on a webpage (scrolling the webpage), that default behavior needs to be suppressed. In jQuery events, this can be done in a cross-browser way by simply returning the value false. However, if not using jQuery, you will need to call ev.preventDefault() on the event in modern browsers, or set ev.returnValue = false in older versions of Internet Explorer.
| Example |
Copy Code
|
|---|---|
function handleGlobalKeypress (ev, viewerControl) {
switch (ev.keyCode) {
case 33: // Page Up
ev.preventDefault();
viewerControl.changeToPrevPage();
return false;
case 34: //Page Down
ev.preventDefault();
viewerControl.changeToNextPage();
return false;
}
}
function initKeyBindings (viewerControl) {
var handler = function(ev){
return handleGlobalKeypress(ev, viewerControl);
};
$(document).on("keydown", handler);
}
|
|
In this example, you will use the J and K keys to navigate search results. In this case, we will set up the keyboard shortcut listener a little differently. Here, you subscribe to keyboard events when a search has completed, and then remove the event listener when the search is cleared. In the listener, you also make sure that the user is not trying to type something by checking the tag name of the event target:
| Example |
Copy Code
|
|---|---|
function doSearch (str, viewerControl) {
var results = [],
i = 0;
var resultNavigationHandler = function (ev) {
var tagName = ev.target.tagName.toLowerCase();
if (tagName === 'input' || tagName === 'textarea') {
return;
}
switch (ev.keyCode) {
case 74: // j
if (i > 0){
viewerControl.setSelectedSearchResult(results[--i], true);
}
break;
case 75: // k
if (i < results.length - 1) {
viewerControl.setSelectedSearchResult(results[++i], true);
}
break;
}
};
var searchRequest = window.sr = viewerControl.search(str);
// add events to the search request
searchRequest.on("SearchCompleted", function(){
results = searchRequest.getResults();
// set the result to the first
viewerControl.setSelectedSearchResult(results[0], true);
// bind key listener when the search is done
$(document).on("keydown", resultNavigationHandler);
});
// listen to when the search is cleared
viewerControl.on("SearchCleared", function(){
// remove key listener when the search is cleared
$(document).off("keydown", resultNavigationHandler);
});
}
|
|
You have now completed all of the examples in this topic.